#include "Common.h"
#include "Headers.h"

namespace Audio
{
	AudioPlayingVoice::AudioPlayingVoice(AudioVoice* v, UINT32 i)
		:voice(v)
		,lowLevelVoice(NULL)
		,stream(NULL)
		,allDataSubmitted(FALSE)
		,isPlaying(FALSE)
		,completeCallback(NULL)
		,id(i)
	{
		buffer = new AudioDataBuffer();
		stream = v->CreateAudioStream();
		voice->AddPlayingVoice(this);
	}
	
	AudioPlayingVoice::~AudioPlayingVoice()
	{
		voice->DeletePlayingVoice(this);
		delete buffer;
		delete stream;
	}
	
	void AudioPlayingVoice::SetInfo(IVoice* lv)
	{
		lowLevelVoice = lv;		
		lowLevelVoice->SetUserData(this);
	}

	BOOL AudioPlayingVoice::IsAllDataSubmited() const
	{
		return allDataSubmitted;
	}
	void AudioPlayingVoice::LoadData()
	{		
		unsigned int size = 64 * 1024;
		unsigned int read = 0;
		unsigned char* newBuffer = buffer->GetNewBuffer(size);
				
		if(!stream->End())
		{
			stream->GetData(newBuffer, size, read);			
			if(read)
			{
				lowLevelVoice->SubmitData(newBuffer, read, allDataSubmitted ? SubmitBuffer_Last : SubmitBuffer_Normal);			
			}
		}
		else
		{
			allDataSubmitted = TRUE;
		}
		return;
	}

	void AudioPlayingVoice::PlayingCompleted()
	{
		isPlaying = false;
		if(completeCallback)
		{
			completeCallback->OnPlayingComplete(GetId());
		}
	}

	void AudioPlayingVoice::Start()
	{
		stream->Rewind();
		LoadData();
		LoadData();
		lowLevelVoice->Start();
		isPlaying = TRUE;
	}

	void AudioPlayingVoice::Start(PlayingCompeletCallback* callback)
	{
		completeCallback = callback;
		Start();
	}

	void AudioPlayingVoice::Resume()
	{
		lowLevelVoice->Start();
		isPlaying = TRUE;
	}

	void AudioPlayingVoice::Stop()
	{
		lowLevelVoice->Stop();
		isPlaying = FALSE;
	}
	BOOL AudioPlayingVoice::IsPlaying()
	{
		return isPlaying;
	}	

	void AudioPlayingVoice::SetVolume(FLOAT vol)
	{
		if(lowLevelVoice != NULL)
		{
			lowLevelVoice->SetVolume(vol);
		}
	}
	FLOAT AudioPlayingVoice::GetVolume()
	{
		if(lowLevelVoice != NULL)
		{
			return lowLevelVoice->GetVolume();
		}
		return 0.0;
	}

	UINT32 AudioPlayingVoice::GetSamplePlayed() const
	{
		if(lowLevelVoice != NULL)
		{
			return lowLevelVoice->GetSamplePlayed();
		}
		return 0;
	}
}
